手指觸控螢幕時觸發
moveImage.setOnTouchListener(mOnTouchListener)
val mOnTouchListener = object : View.OnTouchListener {
override fun onTouch(view: View?, event: MotionEvent?): Boolean {
when (event!!.action and MotionEvent.ACTION_MASK) {
//設置事件
}
//通知 ViewGroup 要接收此事件,事件將不往下傳遞
return true
}
}
MotionEvent.action:
ACTION_DOWN : 第一根手指按下時觸發
ACTION_POINTER_DOWN : 第二、三、四…等等的手指按下時觸發
ACTION_MOVE : 螢幕上觸控點滑動時觸發
ACTION_POINTER_UP : 在螢幕剩一個觸控點之前,手指離開螢幕時觸發
ACTION_UP : 最後一根手指離開螢幕時觸發
#目前測試發現,三指同時按下時,event.pointerCount 會為 2,
且無論手指依序或同時起來,ACTION_POINTER_UP 及 ACTION_UP 皆
不會觸發,這部分仍待了解原因
event:
event.rawX / event.rawY:觸控點相對於螢幕左上角的坐標
event.getX(Index) / event.getY(Index):觸控點相對於 view 自身左上角的坐標
event.pointerCount:目前螢幕上觸控點的數量
event.findPointerIndex(Id):取得觸摸點的 Index 值
event.getPointerId(Index):取得觸摸點的 Id
# Id : 每根手指從按下至離開,會擁有一個固定Id
# Index : 範圍為 [ 0 , pointerCount-1],且每根手指的Index有可能會變動
設置 View 的上下左右邊界
l : view.left
t : view.top
r : view.right = view.left + view.width
b : view.bottom = view.top + view.height
# View.x = view.left + view.translateX
# View.y = view.top + view.translateY
companion object {
val MODE_NONE = 0
val MODE_MOVE = 1
val MODE_ZOOM = 2
}
val mOnTouchListener = object : View.OnTouchListener {
override fun onTouch(view: View?, event: MotionEvent?): Boolean {
when (event!!.action and MotionEvent.ACTION_MASK) {
ACTION_DOWN -> { mode = MODE_MOVE }
ACTION_POINTER_DOWN -> {
if (event.pointerCount <= 2) {
//兩指皆在View內才觸發
if(判斷觸控點是否在 View 內的條件){ mode = MODE_ZOOM }
}
else mode = MODE_NONE
}
ACTION_POINTER_UP -> { mode = MODE_NONE }
}
return true
}
}
目標:找出新位置的 view.x 及 view.y 並設置
作法:
ACTION_DOWN 時先將要扣掉的長度存進變數
ACTION_MOVE 時設定新的 view.x 及 view.y
Code:
ACTION_DOWN -> {
xToSub = event.raxX - view.x
yToSub = event.raxY - view.y
}
ACTION_MOVE -> {
view!!.x = event.rawX - xToSub
view.y = event.rawY - yToSub
}
拖曳邊界
避免 View 跑出畫面回不來
自定義期望的拖曳邊界
ACTION_UP 時,用 view 當前的上下左右判斷是否跑出邊界
若超出邊界,則重新設置 view.x 及 view.y
ACTION_POINTER_DOWN 時取得兩觸控點的距離及中點
# 不能用 event.rawX,因為無法透過 Index 或 Id 取得兩個點分別的 event.rawX
ACTION_MOVE :
透過中點座標及初始距離找移動後 left 的位置
left = midX - (oriX * ratio) + view.translateX
# 沒加 view.translateX 的話求出來的為 view.x
仿照上述方式取得 top
right = left + (原 width * ratio)
bottom = top + (原 height * ratio)
設置 view.layout(left, top, right, bottom)
避免縮到太小
設定 view 的最小長、寬
若 (原 width * ratio) < 最小值,則將 width 設為自定義的最小值
Android
Kotlin
onTouch
MotionEvent
座標系統
多指觸控
View
Layout